// Стандартные
#define _USE_MATH_DEFINES   // Включения определений мат. констант (например числа пи), не прописаных в стандарте C++.
#include <cmath>
// Qt
#include <QtCore/QTextStream>
// Локальные
#include "settings.h"

Settings *Settings::m_Instance = NULL;

//================================================================================================================================
//================================================================================================================================
void Settings::updateSettings()
{
    if(!m_Settings->contains("AppVersion"))
    {
        //************************************************************************************************************************
        // Настройки программы.
        //************************************************************************************************************************
        m_Settings->setValue("AppVersion", qApp->applicationVersion());
        m_Settings->setValue("InputPath", "./input");
        m_Settings->setValue("OutputPath", "./output");
        m_Settings->setValue("BinaryInput", false);

        //************************************************************************************************************************
        // Настройки решателя.
        //************************************************************************************************************************
        m_Settings->setValue("Solver/Solver", true);
        m_Settings->setValue("Solver/SolverType", -1);      //Ручной выбор типа решателя при каждом запуске.
        m_Settings->setValue("Solver/OtputStep", 10);
        m_Settings->setValue("Solver/ResumeFrom", -1);
        m_Settings->setValue("Solver/Solidification", true);
        m_Settings->setValue("Solver/Concentration", false);
        m_Settings->setValue("Solver/Convection", true);
        m_Settings->setValue("Solver/Rotation", false);
        m_Settings->setValue("Solver/Debug", false);


        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Time/Stationarity", false);
        m_Settings->setValue("Time/TimeLayers", 10000);
        m_Settings->setValue("Time/TimeStep", 1.5);
        m_Settings->setValue("Time/TimeMoment", 5000);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Physics/MaxTemperature", 1723.16);
        m_Settings->setValue("Physics/RodTemperature", 0);          //Такая же как и температура в горячей зоне печи.
        m_Settings->setValue("Physics/TemperatureGradient", 34.13);
        m_Settings->setValue("Physics/CrucibleSpeed", 1.4063);
        m_Settings->setValue("Physics/AngularSpeed", 2*M_PI*0.1);   //Один оборот за 10 секунд.
        m_Settings->setValue("Physics/CrucibleRadius", 0.05);
        m_Settings->setValue("Physics/Admixture", "B");
        m_Settings->setValue("Physics/Concentration", 1000);        // Концентрация в ppm.

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Math/SlaeIters", 1000);
        m_Settings->setValue("Math/SlaeResidual", 1e-10);
        m_Settings->setValue("Math/NonlinIters", 500);
        m_Settings->setValue("Math/NonlinResidual", 1e-7);
        m_Settings->setValue("Math/FrontHalfwidth", 0.05);
        m_Settings->setValue("Math/DiffStep", 0.000625);
        m_Settings->setValue("Math/RelaxFactor", 0.5);
        m_Settings->setValue("Math/MinCrystalHeight", 0.);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Si(Solid)/Density", 2550.0);
        m_Settings->setValue("Si(Solid)/HeatCapacity", 714.0);
        m_Settings->setValue("Si(Solid)/HeatConductivity", 30.15);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Si(Liquid)/Density", 2550.0);
        m_Settings->setValue("Si(Liquid)/MolarMass", 28.0855);
        m_Settings->setValue("Si(Liquid)/Viscosity", 3.48e-7);
        m_Settings->setValue("Si(Liquid)/HeatCapacity", 1099.95);
        m_Settings->setValue("Si(Liquid)/Expansiveness", 6.68e-5);
        m_Settings->setValue("Si(Liquid)/HeatConductivity", 42.9);
        m_Settings->setValue("Si(Liquid)/CrystallizationHeat", 1.1053152e6);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("C/Density", 1820.0);
        m_Settings->setValue("C/HeatCapacity", 710.0);
        m_Settings->setValue("C/HeatConductivity", 95);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Ar/Density", 1.5711);
        m_Settings->setValue("Ar/HeatCapacity", 521.8428);
        m_Settings->setValue("Ar/HeatConductivity", 0.055);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("B/MolarMass", 10.811);
        m_Settings->setValue("B/Diffusivity", 2e-14);       //! Временное значение
        m_Settings->setValue("B/SegregationFactor", 0.9);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("Al/MolarMass", 26.98151);
        m_Settings->setValue("Al/Diffusivity", 2e-14);
        m_Settings->setValue("Al/SegregationFactor", 0.003);

        //************************************************************************************************************************
        // Очертания тигля.
        //************************************************************************************************************************
        m_Settings->setValue("Crucible-Cylindrical/R", QVariantList() << 0.000 << 0.055 << 0.000 << 0.050 << 0.000 << 0.050 
            << 0.055 << 0.000 << 0.050 << 0.010 << 0.055 << 0.000 << 0.010);
        m_Settings->setValue("Crucible-Cylindrical/Z", QVariantList() << 0.000 << 0.000 << 0.005 << 0.005 << 0.055 << 0.055
            << 0.055 << 0.060 << 0.060 << 0.065 << 0.065 << 0.115 << 0.115);
        m_Settings->setValue("Crucible-Cylindrical/N", QVariantList() << 44 << 3 << 3 << 39 << 39 << 39 << 44 << 39 << 3 << 3 
            << 3 << 7 << 39 << 3 << 39 << 5 << 39 << 39 << 5);

        m_Settings->setValue("Crucible-Conic/R", QVariantList() << 0.000 << 0.055 << 0.000 << 0.050 << 0.000 << 0.050 
            << 0.055 << 0.000 << 0.050 << 0.010 << 0.055 << 0.000 << 0.010);
        m_Settings->setValue("Crucible-Conic/Z", QVariantList() << 0.000 << 0.055 << 0.005 << 0.055 << 0.105 << 0.105
            << 0.105 << 0.110 << 0.110 << 0.115 << 0.115 << 0.165 << 0.165);
        m_Settings->setValue("Crucible-Conic/N", QVariantList() << 44 << 3 << 3 << 39 << 78 << 39 << 44 << 39 << 3 << 3 
            << 3 << 7 << 39 << 3 << 39 << 5 << 39 << 39 << 5);

        m_Settings->setValue("Crucible-CylindricalConic/R", QVariantList() << 0.000 << 0.055 << 0.000 << 0.050 << 0.000 << 0.050 
            << 0.055 << 0.000 << 0.050 << 0.010 << 0.055 << 0.000 << 0.010 << 0.055);
        m_Settings->setValue("Crucible-CylindricalConic/Z", QVariantList() << 0.000 << 0.055 << 0.005 << 0.055 << 0.105 << 0.105
            << 0.105 << 0.110 << 0.110 << 0.115 << 0.115 << 0.165 << 0.165 << 0.000);
        m_Settings->setValue("Crucible-CylindricalConic/N", QVariantList() << 44 << 3 << 3 << 39 << 78 << 39 << 44 << 39 << 3 << 3 
            << 3 << 7 << 39 << 3 << 39 << 5 << 39 << 39 << 5 << 44 << 44);

        //************************************************************************************************************************
        // Настройки постпроцессора.
        //************************************************************************************************************************
        m_Settings->setValue("Postproc/Postproc", false);
        m_Settings->setValue("Postproc/Bin2Txt", true);
        m_Settings->setValue("Postproc/SpeedProfiles", false);
        m_Settings->setValue("Postproc/TemperatureProfiles", false);
        m_Settings->setValue("Postproc/CrystalMass", false);
        m_Settings->setValue("Postproc/BuildFront", false);
        m_Settings->setValue("Postproc/KineticEnergy", false);
        m_Settings->setValue("Postproc/LocalConductiveHeatFlow", false);
        m_Settings->setValue("Postproc/LocalConvectiveHeatFlow", false);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("SpeedProfiles/FileMask", "*");
        m_Settings->setValue("SpeedProfiles/R", QVariantList() << 0.010 << 0.025 << 0.040);
        m_Settings->setValue("SpeedProfiles/Z", QVariantList() << 0.015 << 0.030 << 0.045);
        m_Settings->setValue("SpeedProfiles/VzAboveFront", false);
        m_Settings->setValue("SpeedProfiles/CentralSections", true);
        m_Settings->setValue("SpeedProfiles/CurvedSectionAboveFront", true);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("TemperatureProfiles/FileMask", "*");
        m_Settings->setValue("TemperatureProfiles/R", QVariantList() << 0.010 << 0.025 << 0.040);
        m_Settings->setValue("TemperatureProfiles/Z", QVariantList() << 0.015 << 0.030 << 0.045);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("LocalConductiveHeatFlow/FileMask", "*");
        m_Settings->setValue("LocalConductiveHeatFlow/R", QVariantList() << 0.010 << 0.025 << 0.040);
        m_Settings->setValue("LocalConductiveHeatFlow/Z", QVariantList() << 0.015 << 0.030 << 0.045);
        m_Settings->setValue("LocalConductiveHeatFlow/FlowFromWall", false);
        m_Settings->setValue("LocalConductiveHeatFlow/FlowAboveFront", true);
        m_Settings->setValue("LocalConductiveHeatFlow/CurvedSectionAboveFront", true);

        //************************************************************************************************************************
        //************************************************************************************************************************
        m_Settings->setValue("LocalConvectiveHeatFlow/FileMask", "*");
        m_Settings->setValue("LocalConvectiveHeatFlow/R", QVariantList() << 0.010 << 0.025 << 0.040);
        m_Settings->setValue("LocalConvectiveHeatFlow/Z", QVariantList() << 0.015 << 0.030 << 0.045);
        m_Settings->setValue("LocalConvectiveHeatFlow/FlowAboveFront", true);
        m_Settings->setValue("LocalConvectiveHeatFlow/CurvedSectionAboveFront", true);

    }
    if(m_Settings->value("AppVersion").toString() != qApp->applicationVersion())
    {
        if(m_Settings->value("AppVersion") == "1.0.0")
        {
            m_Settings->setValue("AppVersion", qApp->applicationVersion());
            m_Settings->setValue("BinaryInput", false);

            m_Settings->setValue("Postproc/Bin2Txt", true);
            m_Settings->setValue("Postproc/SpeedProfiles", false);
            m_Settings->setValue("Postproc/TemperatureProfiles", false);
            m_Settings->setValue("Postproc/LocalConductiveHeatFlow", false);
            m_Settings->setValue("Postproc/LocalConvectiveHeatFlow", false);
        }
        else
        {
            QTextStream cout(stdout);
            cout.setCodec(QTextCodec::codecForName("IBM866"));

            cout << QObject::tr("Неподдерживаемая версия настроек. Обновление невозможно.") << endl;
            cout << QObject::tr("Удалите файл настроек и перезапустите программу.") << endl;
        }
    }

   m_Settings->sync();
}
